// HttpSessionReaper.java - A class that invalidates inactive HttpSessions.
//
// Copyright (C) 1999-2002  Smart Software Consulting
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// Smart Software Consulting
// 1688 Silverwood Court
// Danville, CA  94526-3079
// USA
//
// http://www.smartsc.com
//

package com.smartsc.http;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

class HttpSessionReaper
extends Thread
{
	HttpSessionReaper()
	{
		setDaemon( true);
		start();
	}

	public
	void
	run()
	{
		while( true)
		{
			try { sleep( REAP_PERIOD); }
			catch( InterruptedException ie) { return; }

			timeoutSessions();

			if( ++gcCounter == REAP_PERIODS_PER_GC)
			{
				System.gc();
				gcCounter = 0;
			}
		}
	}

	protected static
	void
	timeoutSessions()
	{
		long now = System.currentTimeMillis();
		Vector oldSessions = new Vector();

		synchronized( HttpRequest.sessions)
		{
			Enumeration e = HttpRequest.sessions.elements();
			while( e.hasMoreElements())
			{
				HttpSession sess = (HttpSession)e.nextElement();
				int maxInactiveInterval = sess.getMaxInactiveInterval();

				long lastAccessedTime;
				if( sess.isNew())
				{
					lastAccessedTime = sess.getCreationTime();
				}
				else
				{
					lastAccessedTime = sess.getLastAccessedTime();
				}

				if( maxInactiveInterval >= 0
				&&  lastAccessedTime < now - maxInactiveInterval*1000 )
				{
					oldSessions.addElement( sess);
				}
			}

			e = oldSessions.elements();
			while( e.hasMoreElements())
			{
				try { ((HttpSession)e.nextElement()).invalidate(); }
				catch( IllegalStateException ise) {}
			}
		}
	}

	private int gcCounter = 0;

	public static final int REAP_PERIOD = 15 * 1000; // 15 seconds
	public static final int REAP_PERIODS_PER_GC = 20; // 5 minutes
}
